package priv.bestbeat.reportcenter.core.pdf;

import com.itextpdf.kernel.geom.LineSegment;
import com.itextpdf.kernel.geom.Vector;
import com.itextpdf.kernel.pdf.canvas.parser.EventType;
import com.itextpdf.kernel.pdf.canvas.parser.data.IEventData;
import com.itextpdf.kernel.pdf.canvas.parser.data.TextRenderInfo;
import com.itextpdf.kernel.pdf.canvas.parser.listener.IEventListener;

import java.util.*;

/**
 * @author bestbeat
 * @date 2022/4/9
 */
public class TextObjEventListener implements IEventListener {

    private Map<String,List<Vector>> textObjMap;

    public TextObjEventListener() {
        this.textObjMap = new HashMap<>();
    }

    public Map<String,List<Vector>> getTextObjMap() {
        return this.textObjMap;
    }

    @Override
    public void eventOccurred(IEventData data, EventType type) {
        if (EventType.BEGIN_TEXT.equals(type)) {
            Entry.create();
        } else if (EventType.END_TEXT.equals(type)) {
            Entry entry = Entry.getSelf();
            this.textObjMap.put(entry.getKey(), entry.getValue());
        } else if (EventType.RENDER_TEXT.equals(type)) {
            TextRenderInfo textRenderInfo = (TextRenderInfo) data;
            LineSegment segment = textRenderInfo.getBaseline();
            // 获取初始位置坐标
            Vector start = segment.getStartPoint();
            Entry entry = Entry.getSelf();
            entry.addVector(start);
            entry.appendText(textRenderInfo.getText());
        } else {

        }
    }

    @Override
    public Set<EventType> getSupportedEvents() {
        Set<EventType> eventTypes = new HashSet<>();
        eventTypes.add(EventType.BEGIN_TEXT);
        eventTypes.add(EventType.END_TEXT);
        eventTypes.add(EventType.RENDER_TEXT);
        return eventTypes;
    }

    private static class Entry {
        private final List<Vector> startVectorsPerObj;
        private final StringBuilder textObj;

        public Entry() {
            this.startVectorsPerObj = new LinkedList<>();
            this.textObj = new StringBuilder();
        }

        private static final ThreadLocal<Entry> THREAD_LOCAL = new ThreadLocal<>();

        public static Entry create() {
            THREAD_LOCAL.set(new Entry());
            return THREAD_LOCAL.get();
        }

        public Entry appendText(String text) {
            this.textObj.append(text);
            return this;
        }

        public Entry addVector(Vector startVector) {
            this.startVectorsPerObj.add(startVector);
            return this;
        }

        public String getKey() {
            return this.textObj.toString();
        }

        public List<Vector> getValue() {
            return this.startVectorsPerObj;
        }

        public static Entry getSelf() {
            return THREAD_LOCAL.get();
        }
    }
}
